package com.asianrapid.core.utils;

import org.apache.commons.lang3.CharSet;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Auther: 迟家鑫
 * @Date: 2018/6/19 13:42
 * @Description:字符串的实用程序类。
 */
public class StringUtils {

	/**
	 * ASCII 文字（数字）
	 */
//	private static CharRange digit = new CharRange('\u0030', '\u0039');

	/**
	 * ASCII 文字（英数字）
	 */
	private static CharSet alphaNumChar = CharSet.getInstance("0-9A-Za-z");

	/**
	 * 许可的mail地址
	 */
	private static CharSet allowedMailAddress = CharSet.getInstance(".@_0-9a-zA-Z-");

    private static final String CHARSET_NAME = "UTF-8";

	private StringUtils() {
	}

    /**
     * 转换为字节数组
     * @param str 需要转换的字符串 转换的格式为utf-8
     * @return
     */
    public static byte[] getBytes(String str){
    	if (str != null){
    		try {
				return str.getBytes(CHARSET_NAME);
			} catch (UnsupportedEncodingException e) {
				return null;
			}
    	}else{
    		return null;
    	}
    }

	/**
	 * 判断字符串是否为空这个为null
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(String str) {
		return str == null || str.length() == 0;
	}

	/**
	 * 判断字符串是否为空或者null，多个空格也算空
	 * @param str
	 * @return
	 */
	public static boolean isBlank(String str) {
		return str == null || str.trim().length() == 0;
	}

	/**
	 * 将字符串强转为整形，如果不可以转换则值为0
	 * @param str 需要转换为数字的字符串
	 * @return
	 */
	public static int conv2Int(String str) {
		int ret = 0;
		try {
			ret = Integer.parseInt(str);
		} catch (NumberFormatException e) {
		}
		return ret;
	}

	/**
	 * 将字符串强转为整形，如果不可以转换则值为默认值
	 * @param str 需要转换为数字的字符串
	 * @param defaultVal 默认值
	 * @return
	 */
	public static int conv2Int(String str, int defaultVal) {
		int ret = defaultVal;
		try {
			ret = Integer.parseInt(str);
		} catch (NumberFormatException e) {
		}
		return ret;
	}

	/**
	 * 将字符串强转为long，如果不可以转换则值为0
	 * @param str 需要转换为数字的字符串
	 * @return
	 */
	public static long conv2Long(String str) {
		long ret = 0;
		try {
			ret = Long.parseLong(str);
		} catch (NumberFormatException e) {
		}
		return ret;
	}

	/**
	 * 将字符串强转为long，如果不可以转换则值为默认值
	 * @param str 需要转换为数字的字符串
	 * @param defaultVal 默认值
	 * @return
	 */
	public static long conv2Long(String str, long defaultVal) {
		long ret = defaultVal;
		try {
			ret = Long.parseLong(str);
		} catch (NumberFormatException e) {
		}
		return ret;
	}

	/**
	 * 拼接count次str字符串
	 * @param str 需要拼接count次的字符串
	 * @param count 需要拼接的次数
	 * @return
	 */
	public static String fill(String str, int count) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < count; ++i) {
			sb.append(str);
		}
		return sb.toString();
	}

	/**
	 * 将byte数组转换成为HexString（此方法返回的字符串表示的无符号整数参数所表示的值以十六进制（基数为16）.）
	 * 即转换为16进制字符串
	 * @param res
	 * @return
	 */
	public static String conv2HexString(byte[] res) {
		StringBuffer sb = new StringBuffer(res.length << 1);
		for (int i = 0; i < res.length; i++) {
			String digit = Integer.toHexString(0xFF & res[i]);
			if (digit.length() == 1) {
				digit = '0' + digit;
			}
			sb.append(digit);
		}
		return sb.toString();
	}

	/**
	 * 对参数的字符串进行  native2ascii 处理的方法。<br>
	 * 第二个参数设置 null的话、使用系统属性 file.encoding设定。
	 *
	 * @param str 变换的字符串
	 * @return native2ascii 字符串
	 * @throws UnsupportedEncodingException 指定不受支持的字符编码
	 */
	public static String native2Ascii(String str)
		throws UnsupportedEncodingException {
		StringBuffer buf = new StringBuffer(str.length() * 6);
		char[] carray = str.toCharArray();
		for (int i = 0; i < carray.length; i++) {
			if (carray[i] > '\u007f') {
				buf.append("\\u");
				String hex4 = Integer.toHexString((int)carray[i]);
				if (hex4.length() == 3) {
					hex4 = "0" + hex4;
				} else if (hex4.length() == 2) {
					hex4 = "00" + hex4;
				} else if (hex4.length() == 1) {
					hex4 = "000" + hex4;
				}
				buf.append(hex4);
			}
			else {
				buf.append(carray[i]);
			}
		}
		return buf.toString();
	}

	/**
	 * 通过传递指定的编码返回转换后的 Unicode 转义字符串的方法。
	 *
	 * @param str 转义的 Unicode ASCII 字符串
	 * @param encoding 字符编码
	 * @return ascii 变换的字符串
	 * @throws UnsupportedEncodingException 指定不受支持的字符编码
	 */
	public static String ascii2Native(String str, String encoding)
		throws UnsupportedEncodingException {
		String sysEnc = System.getProperty("file.encoding");
		if (encoding == null) {
			encoding = sysEnc;
		}
		System.setProperty("file.encoding", encoding);

		StringBuffer buf = new StringBuffer();
		char[] carray = str.toCharArray();
		for (int i = 0; i < carray.length; i++) {
			// 字符串是 \u9999 格式的情况
			if (carray[i] == '\\'
				&& i + 1 < carray.length
				&& carray[i + 1] == 'u' && i + 5 < carray.length
				&& "0123456789abcdefABCDEF".indexOf(carray[i + 2]) > -1
				&& "0123456789abcdefABCDEF".indexOf(carray[i + 3]) > -1
				&& "0123456789abcdefABCDEF".indexOf(carray[i + 4]) > -1
				&& "0123456789abcdefABCDEF".indexOf(carray[i + 5]) > -1
			) {
				StringBuffer hex4 = new StringBuffer(4);
				for (int k = i + 2; k < i + 6; k++) {
					hex4.append(carray[k]);
				}
				buf.append((char)Integer.parseInt(hex4.toString(), 16));
				i = i + 5;
			} else {
				buf.append(carray[i]);
			}
		}

		System.setProperty("file.encoding", sysEnc);
		return buf.toString();
	}

	/**
	 * 取得UUID。
	 *
	 * @return UUID
	 */
	public static String getUUID() {
		UUID uuid = UUID.randomUUID();
		return uuid.toString().replace("-", "");
	}

	/**
	 * 生成随机密码
	 * @param pwdLen 生成的密码的总长度
	 * @return 密码的字符串
	 */
	public static String genRandomNum(int pwdLen) {
		//35是因为数组是从0开始的，26个字母+10个 数字
		final int maxNum = 36;
		int i;  //生成的随机数
		int count = 0; //生成的密码的长度
		char[] str = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
				'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
				'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

		StringBuffer pwd = new StringBuffer("");
		Random r = new Random();
		while(count < pwdLen){
			//生成随机数，取绝对值，防止 生成负数，
			i = Math.abs(r.nextInt(maxNum));  //生成的数最大为36-1
			if (i >= 0 && i < str.length) {
				if (i%2 ==0) {
					pwd.append(Character.toUpperCase(str[i]));
				} else {
					pwd.append(str[i]);
				}
				count ++;
			}
		}

		return pwd.toString();
	}

	/**
	 * 字符串是正整数的判定方法。
	 *
	 * @param str 字符串
	 * @return 数字 0-9 true
	 */
	public static boolean isNubmer(String str) {
	    Pattern pattern = Pattern.compile("[0-9]*");
	    Matcher isNum = pattern.matcher(str);
	    if( !isNum.matches() ){
	        return false;
	    }
	    return true;
	}

	/**
	 * 字符串前后空格（全角，半角）的trim
	 *
	 * @param orgstr 文字列
	 * @return trim后的文字列
	 */
	public static String trim(String orgstr) {
		while (orgstr.startsWith(" ") || orgstr.startsWith("　")) {
			orgstr = orgstr.substring(1);
		}
		while (orgstr.endsWith(" ") || orgstr.endsWith("　")) {
			orgstr = orgstr.substring(0, orgstr.length() - 1);
		}
		return orgstr;
	}

	/**
	 * 返回24位当前系统时间的纳秒值
	 *
	 * @return 请求流水号
	 */
	public static String createRequestNo() {
		String nano = String.valueOf(System.nanoTime());
		return DateUtils.getTimeStamp() + nano.substring(nano.length()-7);
	}

	/**
	 * 判断字符串是数字，最多包含两位小数
	 * @param str
	 * @return
	 */
	public static boolean isSettingNum(String str) {
		String regex = "^([1-9]\\d*)$|^(0|[1-9]\\d*)\\.(\\d{1,2})$|^0$";
		return match(regex, str);
	}

	/**
	* @param regex
	* 正则表达式字符串
	* @param str
	* 要匹配的字符串
	* @return 如果str 符合 regex的正则表达式格式,返回true, 否则返回 false;
	*/
	public static boolean match(String regex, String str) {
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}

	/**
	 * 判断是否为登录的账号3-15为包含数字和大小写字母
	 * @param str
	 * @return
	 */
	public static boolean isLoginId(String str) {
		String regex = "^[a-zA-z][a-zA-Z0-9_]{3,15}$";
		return match(regex, str);
	}

	/**
	 * 判断是否为密码 8-20位 必须包含大小写字母、数字和特殊字符
	 * @param str
	 * @return
	 */
	public static boolean isPasswordStrength(String str) {
		String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)(?![`~!@#$%^&*()_+=\\\\|{}\\[\\]'\":;,.<>/?-]+$)[`~!@#$%^&*()_+=\\\\|{}\\[\\]'\":;,.<>/?0-9a-zA-Z-]{8,20}$";
		return match(regex, str);
	}

	/**
	 * 密码验证  最大到20位 必须包含大小写字母、数字和特殊字符
	 * @param str 输入的密码
	 * @param len 密码最小长度
	 * @return
	 */
	public static boolean isPasswordStrength(String str, int len) {

		if (len < 1) {
			len = 8;
		}
		String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)(?![`~!@#$%^&*()_+=\\\\|{}\\[\\]'\":;,.<>/?-]+$)[`~!@#$%^&*()_+=\\\\|{}\\[\\]'\":;,.<>/?0-9a-zA-Z-]{" + len +",20}$";
		return match(regex, str);
	}

	/**
	 * 功能：身份证的有效验证
	 *
	 * @param IDStr
	 *            身份证号
	 * @return 有效：返回"" 无效：返回String信息
	 * @throws ParseException
	 */
	public static boolean isIdCard(String IDStr)  {
		String[] ValCodeArr = { "1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2" };
		String[] Wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2" };
		String Ai = "";
			try {
			// ================ 号码的长度 15位或18位 ================
			if (IDStr.length() != 15 && IDStr.length() != 18) {
				return false;
			}
			// =======================(end)========================

			// ================ 数字 除最后以为都为数字 ================
			if (IDStr.length() == 18) {
				Ai = IDStr.substring(0, 17);
			} else if (IDStr.length() == 15) {
				Ai = IDStr.substring(0, 6) + "19" + IDStr.substring(6, 15);
			}
			// 身份证15位号码都应为数字 ; 18位号码除最后一位外，都应为数字。
			if (isAsciiAlphaNumCharOnly(Ai) == false) {
				return false;
			}
			// =======================(end)========================

			// ================ 出生年月是否有效 ================
			String strYear = Ai.substring(6, 10);// 年份
			String strMonth = Ai.substring(10, 12);// 月份
			String strDay = Ai.substring(12, 14);// 月份
			if (isDate(strYear + "-" + strMonth + "-" + strDay) == false) {
				// 身份证生日无效
				return false;
			}
			GregorianCalendar gc = new GregorianCalendar();
			SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");

			if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150
					|| (gc.getTime().getTime() - s.parse(strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) {
				// 身份证生日不在有效范围。
				return false;
			}

			if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) {
				// 身份证月份无效
				return false;
			}
			if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) {
				// 身份证日期无效
				return false;
			}
			// =====================(end)=====================

			// ================ 地区码时候有效 ================
			Hashtable<String, String> h = getAreaCode();
			if (h.get(Ai.substring(0, 2)) == null) {
				// 身份证地区编码错误。
				return false;
			}
			// ==============================================

			// ================ 判断最后一位的值 ================
			int TotalmulAiWi = 0;
			for (int i = 0; i < 17; i++) {
				TotalmulAiWi = TotalmulAiWi + Integer.parseInt(String.valueOf(Ai.charAt(i))) * Integer.parseInt(Wi[i]);
			}
			int modValue = TotalmulAiWi % 11;
			String strVerifyCode = ValCodeArr[modValue];
			Ai = Ai + strVerifyCode;

			if (IDStr.length() == 18) {
				if (Ai.equals(IDStr.toLowerCase()) == false) {
					// 身份证无效，不是合法的身份证号码
					return false;
				}
			}
		} catch (NumberFormatException e) {
			return false;
		} catch (ParseException e) {
			return false;
		}
		// =====================(end)=====================
		return true;
	}

	/**
	 * 功能：设置地区编码（身份证校验使用）
	 *
	 * @return Hashtable 对象
	 */
	private static Hashtable<String, String> getAreaCode() {
		Hashtable<String, String> hashtable = new Hashtable<>();
		hashtable.put("11", "北京");
		hashtable.put("12", "天津");
		hashtable.put("13", "河北");
		hashtable.put("14", "山西");
		hashtable.put("15", "内蒙古");
		hashtable.put("21", "辽宁");
		hashtable.put("22", "吉林");
		hashtable.put("23", "黑龙江");
		hashtable.put("31", "上海");
		hashtable.put("32", "江苏");
		hashtable.put("33", "浙江");
		hashtable.put("34", "安徽");
		hashtable.put("35", "福建");
		hashtable.put("36", "江西");
		hashtable.put("37", "山东");
		hashtable.put("41", "河南");
		hashtable.put("42", "湖北");
		hashtable.put("43", "湖南");
		hashtable.put("44", "广东");
		hashtable.put("45", "广西");
		hashtable.put("46", "海南");
		hashtable.put("50", "重庆");
		hashtable.put("51", "四川");
		hashtable.put("52", "贵州");
		hashtable.put("53", "云南");
		hashtable.put("54", "西藏");
		hashtable.put("61", "陕西");
		hashtable.put("62", "甘肃");
		hashtable.put("63", "青海");
		hashtable.put("64", "宁夏");
		hashtable.put("65", "新疆");
		hashtable.put("71", "台湾");
		hashtable.put("81", "香港");
		hashtable.put("82", "澳门");
		hashtable.put("91", "国外");
		return hashtable;
	}

	/**
	 * 字符串是英数字的判定方法。（身份证校验使用）
	 *
	 * @param str 字符串
	 * @return 英数字 true
	 */
	public static boolean isAsciiAlphaNumCharOnly(String str) {
		boolean asciiOnly = true;
		if (StringUtils.isEmpty(str)) {
			return asciiOnly;
		}
		char[] cs = str.toCharArray();
		for (int i = 0; i < cs.length; i++) {
			if (!alphaNumChar.contains(cs[i])) {
				asciiOnly = false;
			}
		}
		return asciiOnly;
	}

	/**
	 * 功能：判断字符串是否为日期格式
	 *
	 * @param strDate
	 * @return
	 */
	public static boolean isDate(String strDate) {
		Pattern pattern = Pattern
				.compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$");
		Matcher m = pattern.matcher(strDate);
		if (m.matches()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断字符串是否是手机号
	 * @param str
	 * @return
	 */
	public static boolean isMobileNum(String str) {
		String regex = "^13[0-9]{9}$|14[0-9]{9}|15[0-9]{9}$|17[0-9]{9}$|18[0-9]{9}$";
		return match(regex, str);
	}

	/**
	 * 判断是否为特殊字符
	 * `~!@#$%^&*()+=|{}':;',\[\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？
	 * @param str
	 * @return
	 */
	public static boolean isSpecialChar(String str) {
		  String regEx = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
		  Pattern p = Pattern.compile(regEx);
		  Matcher m = p.matcher(str);
		  return m.find();
	}

	/**
	 * mail地址是否许可的检查。
	 *
	 * @param mailAddress mail地址
	 * @return 许可  true
	 */
	public static boolean isAllowedMailAddress(String mailAddress) {
		if (StringUtils.isEmpty(mailAddress)) {
			return false;
		}
		boolean allowed = true;
		char[] cs = mailAddress.toCharArray();
		for (int i = 0; i < cs.length; i++) {
			if (!allowedMailAddress.contains(cs[i])) {
				allowed = false;
				break;
			}
		}
		return allowed;
	}

	/**
	 * 检查充值金额是否正确的方法。<br />
	 * 充值的金额，100的倍数，不大于10,000,000。
	 *
	 * @param str 要验证的字符串
	 * @return 正确返回true，否则返回false
	 */
	public static boolean isRechargeAmount(String str) {
		String regex = "^(\\d{1,5}|100000)0{2}$";
		return match(regex, str);
	}

	/**
	 * 判断String数组中是否包含val这个元素
	 * @param arr String数组
	 * @param val 是否包含这个元素
	 * @return
	 */
	public static boolean isInArray(String[] arr, String val) {
		return Arrays.asList(arr).contains(val);
	}

	/**
	 * 字符串是数值(含小数)的判定方法。
	 *
	 * @param str 字符串
	 * @return 数值(含小数) true
	 */
	public static boolean isNumeric(String str) {
		if (StringUtils.isEmpty(str)) {
			return false;
		}
		Pattern p = Pattern.compile("^\\d+(\\.\\d+)?$");
		Matcher m = p.matcher(str);
		return m.find();
	}

	/**
	 * 字符串替换。
	 * @param strInput 需要替换的字符串
	 * @param strBefore 需要替换的字符或字符串
	 * @param strAfter 替换的字符串
	 * @return 替换后字符串
	 */
	public static String replaceStr(String strInput, String strBefore, String strAfter) {
		if (strInput == null || "".equals(strInput)) {
			return "";
		} else {
			return strInput.replace(strBefore, strAfter);
		}
	}

	/**
	 * 判断是否为url
	 * @param str
	 * @return
	 */
	public static boolean isUrl(String str) {
		String regex = "^(\\w+:\\/\\/)?\\w+(\\.\\w+)+.*$";
		return match(regex, str);
	}

	/**
	 * 判断是否为住宅电话
	 * @param str
	 * @return
	 */
	public static boolean isTelNum(String str) {
		String regex = "\\d{3,5}-\\d{7,8}(-\\d{1,})?$";
		return match(regex, str);
	}

	/**
	 * 手机号中间4位用*显示。
	 *
	 * @return 替换后手机号
	 */
	public static String encryptMobile(String mobile) {
		if (mobile == null || "".equals(mobile)) {
			return "";
		} else {
			String ret = mobile.substring(0,3);
			ret = ret + "****";
			ret = ret + mobile.substring(7,11);
			return ret;
		}
	}

	/**
	 * 邮箱加密
	 * @param email
	 * @return
	 */
	public static String encryptEmail(String email) {
		if (email == null || "".equals(email)) {
			return "";
		} else {
			String ret = email.substring(0,1);
			ret = ret + "****";
			ret = ret + email.substring(email.length() - 1);
			return ret;
		}
	}

	/**
	 * 姓名加密
	 * @param name
	 * @return
	 */
	public static String encryptName(String name) {
		if (name == null || "".equals(name)) {
			return "";
		} else {
			String ret = name.substring(0,1);
			ret = ret + "**";
			return ret;
		}
	}

	/**
	 * 身份证号加密
	 * @param idCard
	 * @return
	 */
	public static String encryptIdCard(String idCard) {
		if (idCard == null || "".equals(idCard)) {
			return "";
		} else {
			String ret = idCard.substring(0,6);
			ret = ret + "************";
			return ret;
		}
	}

	/**
	 * 身份证号加密显示最后几位
	 * @param idCard
	 * @return
	 */
	public static String newEncryptIdCard(String idCard) {
		if (idCard == null || "".equals(idCard)) {
			return "";
		} else {
			String ret = idCard.substring(0,6);
			ret = ret + "********";
			ret = ret + idCard.substring(14);
			return ret;
		}
	}

	/**
	 * 加密银行卡号
	 * @param bankCard
	 * @return
	 */
	public static String encryptBankCard(String bankCard) {
		if (bankCard == null || "".equals(bankCard)) {
			return "";
		} else {
			int len = bankCard.length();
			if(len > 7) {
				String ret = bankCard.substring(0,4);
				ret = ret + "******";
				ret = ret + bankCard.substring(len-3,len);
				return ret;
			}
			return bankCard;
		}
	}

	/**
	 * 字符串截取前面的length位字符串，之后拼接...
	 * @param str 需要拼接...的字符串
	 * @param length 需要截取的位数
	 * @return 截取后字符串
	 */
	public static String getSubString(String str, int length) {
		int count = 0;
		int offset = 0;
		char[] c = str.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (c[i] > 256) {
				offset = 2;
				count += 2;
			} else {
				offset = 1;
				count++;
			}
			if (count == length) {
				int countRemain = 0;
				for (int j = i + 1; j < c.length; j++) {
					if (c[i] > 256) {
						countRemain += 2;
					} else {
						countRemain++;
					}
				}
				if (countRemain <= 3) {
					return str;
				} else {
					return str.substring(0, i + 1) + "...";
				}
			}
			if ((count == length + 1 && offset == 2)) {
				int countRemain = 0;
				for (int j = i + 1; j < c.length; j++) {
					if (c[i] > 256) {
						countRemain += 2;
					} else {
						countRemain++;
					}
				}
				if (countRemain <= 3) {
					return str;
				} else {
					return str.substring(0, i) + "...";
				}
			}
		}
		return str;
	}

	/**
	 * 邮箱地址校验
	 * @param str
	 * @return
	 */
	public static boolean isEmail(String str) {
		String regex = "^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
		return match(regex, str);
	}

	/**
     * 根据身份证的号码算出当前身份证持有者的性别和年龄 18位身份证 <br>
     * @param CardCode 身份证号字符串
     * key：  sex         男，女
     * key：  sexValue    1 ，0
     * key：  age
     * @return
     * @throws Exception
     */
    public static Map<String, Object> getCarInfo(String CardCode)
            throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        String year = CardCode.substring(6).substring(0, 4);// 得到年份
        String yue = CardCode.substring(10).substring(0, 2);// 得到月份
        // String day=CardCode.substring(12).substring(0,2);//得到日
        String sex = "";
        String sexValue = "";
        if (Integer.parseInt(CardCode.substring(16).substring(0, 1)) % 2 == 0) {// 判断性别
            sex = "女";
            sexValue = "1";
        } else {
            sex = "男";
            sexValue = "0";
        }
        Date date = new Date();// 得到当前的系统时间
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String fyear = format.format(date).substring(0, 4);// 当前年份
        String fyue = format.format(date).substring(5, 7);// 月份
        // String fday=format.format(date).substring(8,10);
        int age = 0;
        if (Integer.parseInt(yue) <= Integer.parseInt(fyue)) { // 当前月份大于用户出身的月份表示已过生
            age = Integer.parseInt(fyear) - Integer.parseInt(year) + 1;
        } else {// 当前用户还没过生
            age = Integer.parseInt(fyear) - Integer.parseInt(year);
        }
        map.put("sex", sex);
        map.put("sexValue", sexValue);
        map.put("age", age);
        return map;
    }


	/**
	 * 判断给定字符串是否空白串 空白串是指由空格、制表符、回车符、换行符组成的字符串
	 * 若输入字符串为null或空字符串，返回true
	 * @param input
	 * @return 为空返回true
	 */
    public static boolean isJsonEmpty(CharSequence input) {
        if (input == null || "".equals(input)||"null".equals(input))
            return true;

        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
                return false;
            }
        }
        return true;
    }

	/**判断是否为金额        decimal 11，2
	 * @param str
	 * @return
	 */
	public static boolean isMoneyEleven(Object str) {
		String temp = String.valueOf(str);
		if (str == null) {
			return false;
		} else {
			try {
				if( temp.indexOf(",") >= 0 ){
					String[] arr = temp.split(",");
					if(arr[0].length() > 3 || arr[0].length() == 0){
						return false;
					}
					for(int i = 1;i < arr.length;i++){
						if(arr[i].length() >= 3 ){
							String a = arr[i];
							String[] arr1 = a.split("\\.");
							if(arr1.length == 2){
								if(arr1[0].length() > 3){
									return false;
								}else if(arr1[0].length() < 3 ){
									return false;
								}
								if(arr1[1].length() > 2){
									return false;
								}
							}
						}else if(arr[i].length() < 3){
							return false;
						}
					}
				}
				temp = temp.trim().replace(",", "");
				BigDecimal bigDecimal = new BigDecimal(temp);
				if(temp.length() <= 12){
					String regex = "^([1-9]\\d{0,8})$|^(0|[1-9]\\d{0,8})\\.(\\d{1,2})$|^0$";
					return match(regex, String.valueOf(bigDecimal));
				}
				return false;
			} catch (Exception ex) {
				return false;
			}
		}
	}

	/**
	 * 字符串是数值(不含小数)的判定方法。
	 *
	 * @param str 字符串
	 * @return 数值(含小数) true
	 */
	public static boolean isInteger(String str) {
		if (StringUtils.isEmpty(str)) {
			return false;
		}
		Pattern p = Pattern.compile("^\\d+$");
		Matcher m = p.matcher(str);
		return m.find();
	}


	/**
	 * 字符串长度的判定方法。
	 *
	 * @param str 字符串
	 * @return 符合长度返回 true
	 */
	public static boolean stringRange(String str, int start, int end) {
		if (StringUtils.isEmpty(str)) {
			return false;
		}
		if(str.length() >= start && str.length() <= end){
			return true;
		}
		return false;
	}

	/**
	 * 判断路径是不是合法的图片路径  支持jpg,gif,png
	 * @param value
	 * @return
	 */
	public static boolean isImgURL(String value) {
		if (StringUtils.isEmpty(value)) {
			return false;
		}
		String[] split = value.split("\\.");
		String suffix = split[1].toLowerCase();
		if("jpg".equals(suffix) || "gif".equals(suffix) || "png".equals(suffix)){
			return true;
		}
		return false;
	}

	private static final int INDEX_NOT_FOUND = -1;
	private static final String EMPTY = "";
	/**
	 * <p>
	 * The maximum size to which the padding constant(s) can expand.
	 * </p>
	 */
	private static final int PAD_LIMIT = 8192;

	/**
	 * 功能：将半角的符号转换成全角符号.(即英文字符转中文字符)
	 *
	 * @param str
	 *            源字符串
	 * @return String
	 */
	public static String changeToFull(String str) {
		String source = "1234567890!@#$%^&*()abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_=+\\|[];:'\",<.>/?";
		String[] decode = { "１", "２", "３", "４", "５", "６", "７", "８", "９", "０",
				"！", "＠", "＃", "＄", "％", "︿", "＆", "＊", "（", "）", "ａ", "ｂ",
				"ｃ", "ｄ", "ｅ", "ｆ", "ｇ", "ｈ", "ｉ", "ｊ", "ｋ", "ｌ", "ｍ", "ｎ",
				"ｏ", "ｐ", "ｑ", "ｒ", "ｓ", "ｔ", "ｕ", "ｖ", "ｗ", "ｘ", "ｙ", "ｚ",
				"Ａ", "Ｂ", "Ｃ", "Ｄ", "Ｅ", "Ｆ", "Ｇ", "Ｈ", "Ｉ", "Ｊ", "Ｋ", "Ｌ",
				"Ｍ", "Ｎ", "Ｏ", "Ｐ", "Ｑ", "Ｒ", "Ｓ", "Ｔ", "Ｕ", "Ｖ", "Ｗ", "Ｘ",
				"Ｙ", "Ｚ", "－", "＿", "＝", "＋", "＼", "｜", "【", "】", "；", "：",
				"'", "\"", "，", "〈", "。", "〉", "／", "？" };
		String result = "";
		for (int i = 0; i < str.length(); i++) {
			int pos = source.indexOf(str.charAt(i));
			if (pos != -1) {
				result += decode[pos];
			} else {
				result += str.charAt(i);
			}
		}
		return result;
	}

	/**
	 * 功能：cs串中是否一个都不包含字符数组searchChars中的字符。
	 *
	 * @param cs
	 *            字符串
	 * @param searchChars
	 *            字符数组
	 * @return boolean 都不包含返回true，否则返回false。
	 */
	public static boolean containsNone(CharSequence cs, char... searchChars) {
		if (cs == null || searchChars == null) {
			return true;
		}
		int csLen = cs.length();
		int csLast = csLen - 1;
		int searchLen = searchChars.length;
		int searchLast = searchLen - 1;
		for (int i = 0; i < csLen; i++) {
			char ch = cs.charAt(i);
			for (int j = 0; j < searchLen; j++) {
				if (searchChars[j] == ch) {
					if (Character.isHighSurrogate(ch)) {
						if (j == searchLast) {
							// missing low surrogate, fine, like
							// String.indexOf(String)
							return false;
						}
						if (i < csLast
								&& searchChars[j + 1] == cs.charAt(i + 1)) {
							return false;
						}
					} else {
						// ch is in the Basic Multilingual Plane
						return false;
					}
				}
			}
		}
		return true;
	}

	/**
	 * <p>
	 * 编码为Unicode，格式 '\u0020'.
	 * </p>
	 *         <pre>
	 *   CharUtils.unicodeEscaped(' ') = "\u0020"
	 *   CharUtils.unicodeEscaped('A') = "\u0041"
	 * </pre>
	 *
	 * @param ch
	 *            源字符串
	 * @return 转码后的字符串
	 * @date 2014年06月24日
	 */
	public static String unicodeEscaped(char ch) {
		if (ch < 0x10) {
			return "\\u000" + Integer.toHexString(ch);
		} else if (ch < 0x100) {
			return "\\u00" + Integer.toHexString(ch);
		} else if (ch < 0x1000) {
			return "\\u0" + Integer.toHexString(ch);
		}
		return "\\u" + Integer.toHexString(ch);
	}

	/**
	 * <p>
	 * 进行tostring操作，如果传入的是null，返回空字符串。
	 * </p>
	 *
	 * <pre>
	 * ObjectUtils.toString(null)         = ""
	 * ObjectUtils.toString("")           = ""
	 * ObjectUtils.toString("bat")        = "bat"
	 * ObjectUtils.toString(Boolean.TRUE) = "true"
	 * </pre>
	 *
	 * @param obj
	 *            源
	 * @return String
	 */
	public static String toString(Object obj) {
		return obj == null ? "" : obj.toString();
	}

	/**
	 * <p>
	 * 进行tostring操作，如果传入的是null，返回指定的默认值。
	 * </p>
	 *
	 * <pre>
	 * ObjectUtils.toString(null, null)           = null
	 * ObjectUtils.toString(null, "null")         = "null"
	 * ObjectUtils.toString("", "null")           = ""
	 * ObjectUtils.toString("bat", "null")        = "bat"
	 * ObjectUtils.toString(Boolean.TRUE, "null") = "true"
	 * </pre>
	 *
	 * @param obj
	 *            源
	 * @param nullStr
	 *            如果obj为null时返回这个指定值
	 * @return String
	 */
	public static String toString(Object obj, String nullStr) {
		return obj == null ? nullStr : obj.toString();
	}

	/**
	 * <p>
	 * 只从源字符串中移除指定开头子字符串.
	 * </p>
	 *
	 * <pre>
	 * StringUtil.removeStart(null, *)      = null
	 * StringUtil.removeStart("", *)        = ""
	 * StringUtil.removeStart(*, null)      = *
	 * StringUtil.removeStart("www.domain.com", "www.")   = "domain.com"
	 * StringUtil.removeStart("domain.com", "www.")       = "domain.com"
	 * StringUtil.removeStart("www.domain.com", "domain") = "www.domain.com"
	 * StringUtil.removeStart("abc", "")    = "abc"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param remove
	 *            将要被移除的子字符串
	 * @return String
	 */
	public static String removeStart(String str, String remove) {
		if (isEmpty(str) || isEmpty(remove)) {
			return str;
		}
		if (str.startsWith(remove)) {
			return str.substring(remove.length());
		}
		return str;
	}

	/**
	 * <p>
	 * 只从源字符串中移除指定结尾的子字符串.
	 * </p>
	 *
	 * <pre>
	 * StringUtil.removeEnd(null, *)      = null
	 * StringUtil.removeEnd("", *)        = ""
	 * StringUtil.removeEnd(*, null)      = *
	 * StringUtil.removeEnd("www.domain.com", ".com.")  = "www.domain.com"
	 * StringUtil.removeEnd("www.domain.com", ".com")   = "www.domain"
	 * StringUtil.removeEnd("www.domain.com", "domain") = "www.domain.com"
	 * StringUtil.removeEnd("abc", "")    = "abc"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param remove
	 *            将要被移除的子字符串
	 * @return String
	 */
	public static String removeEnd(String str, String remove) {
		if (isEmpty(str) || isEmpty(remove)) {
			return str;
		}
		if (str.endsWith(remove)) {
			return str.substring(0, str.length() - remove.length());
		}
		return str;
	}

	/**
	 * <p>
	 * 将一个字符串重复N次
	 * </p>
	 *
	 * <pre>
	 * StringUtil.repeat(null, 2) = null
	 * StringUtil.repeat("", 0)   = ""
	 * StringUtil.repeat("", 2)   = ""
	 * StringUtil.repeat("a", 3)  = "aaa"
	 * StringUtil.repeat("ab", 2) = "abab"
	 * StringUtil.repeat("a", -2) = ""
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param repeat
	 *            重复的次数
	 * @return String
	 */
	public static String repeat(String str, int repeat) {
		// Performance tuned for 2.0 (JDK1.4)

		if (str == null) {
			return null;
		}
		if (repeat <= 0) {
			return EMPTY;
		}
		int inputLength = str.length();
		if (repeat == 1 || inputLength == 0) {
			return str;
		}
		if (inputLength == 1 && repeat <= PAD_LIMIT) {
			return repeat(str.charAt(0), repeat);
		}

		int outputLength = inputLength * repeat;
		switch (inputLength) {
			case 1:
				return repeat(str.charAt(0), repeat);
			case 2:
				char ch0 = str.charAt(0);
				char ch1 = str.charAt(1);
				char[] output2 = new char[outputLength];
				for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
					output2[i] = ch0;
					output2[i + 1] = ch1;
				}
				return new String(output2);
			default:
				StringBuilder buf = new StringBuilder(outputLength);
				for (int i = 0; i < repeat; i++) {
					buf.append(str);
				}
				return buf.toString();
		}
	}

	/**
	 * <p>
	 * 将一个字符串重复N次，并且中间加上指定的分隔符
	 * </p>
	 *
	 * <pre>
	 * StringUtil.repeat(null, null, 2) = null
	 * StringUtil.repeat(null, "x", 2)  = null
	 * StringUtil.repeat("", null, 0)   = ""
	 * StringUtil.repeat("", "", 2)     = ""
	 * StringUtil.repeat("", "x", 3)    = "xxx"
	 * StringUtil.repeat("?", ", ", 3)  = "?, ?, ?"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param separator
	 *            分隔符
	 * @param repeat
	 *            重复次数
	 * @return String
	 */
	public static String repeat(String str, String separator, int repeat) {
		if (str == null || separator == null) {
			return repeat(str, repeat);
		} else {
			// given that repeat(String, int) is quite optimized, better to rely
			// on it than try and splice this into it
			String result = repeat(str + separator, repeat);
			return removeEnd(result, separator);
		}
	}

	/**
	 * <p>
	 * 将某个字符重复N次.
	 * </p>
	 *
	 * @param ch
	 *            某个字符
	 * @param repeat
	 *            重复次数
	 * @return String
	 */
	public static String repeat(char ch, int repeat) {
		char[] buf = new char[repeat];
		for (int i = repeat - 1; i >= 0; i--) {
			buf[i] = ch;
		}
		return new String(buf);
	}

	/**
	 * <p>
	 * 字符串长度达不到指定长度时，在字符串右边补指定的字符.
	 * </p>
	 *
	 * <pre>
	 * StringUtil.rightPad(null, *, *)     = null
	 * StringUtil.rightPad("", 3, 'z')     = "zzz"
	 * StringUtil.rightPad("bat", 3, 'z')  = "bat"
	 * StringUtil.rightPad("bat", 5, 'z')  = "batzz"
	 * StringUtil.rightPad("bat", 1, 'z')  = "bat"
	 * StringUtil.rightPad("bat", -1, 'z') = "bat"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param size
	 *            指定的长度
	 * @param padChar
	 *            进行补充的字符
	 * @return String
	 */
	public static String rightPad(String str, int size, char padChar) {
		if (str == null) {
			return null;
		}
		int pads = size - str.length();
		if (pads <= 0) {
			return str; // returns original String when possible
		}
		if (pads > PAD_LIMIT) {
			return rightPad(str, size, String.valueOf(padChar));
		}
		return str.concat(repeat(padChar, pads));
	}

	/**
	 * <p>
	 * 扩大字符串长度，从左边补充指定字符
	 * </p>
	 *
	 * <pre>
	 * StringUtil.rightPad(null, *, *)      = null
	 * StringUtil.rightPad("", 3, "z")      = "zzz"
	 * StringUtil.rightPad("bat", 3, "yz")  = "bat"
	 * StringUtil.rightPad("bat", 5, "yz")  = "batyz"
	 * StringUtil.rightPad("bat", 8, "yz")  = "batyzyzy"
	 * StringUtil.rightPad("bat", 1, "yz")  = "bat"
	 * StringUtil.rightPad("bat", -1, "yz") = "bat"
	 * StringUtil.rightPad("bat", 5, null)  = "bat  "
	 * StringUtil.rightPad("bat", 5, "")    = "bat  "
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param size
	 *            扩大后的长度
	 * @param padStr
	 *            在右边补充的字符串
	 * @return String
	 */
	public static String rightPad(String str, int size, String padStr) {
		if (str == null) {
			return null;
		}
		if (isEmpty(padStr)) {
			padStr = " ";
		}
		int padLen = padStr.length();
		int strLen = str.length();
		int pads = size - strLen;
		if (pads <= 0) {
			return str; // returns original String when possible
		}
		if (padLen == 1 && pads <= PAD_LIMIT) {
			return rightPad(str, size, padStr.charAt(0));
		}

		if (pads == padLen) {
			return str.concat(padStr);
		} else if (pads < padLen) {
			return str.concat(padStr.substring(0, pads));
		} else {
			char[] padding = new char[pads];
			char[] padChars = padStr.toCharArray();
			for (int i = 0; i < pads; i++) {
				padding[i] = padChars[i % padLen];
			}
			return str.concat(new String(padding));
		}
	}

	/**
	 * <p>
	 * 扩大字符串长度，从左边补充空格
	 * </p>
	 *
	 * <pre>
	 * StringUtil.leftPad(null, *)   = null
	 * StringUtil.leftPad("", 3)     = "   "
	 * StringUtil.leftPad("bat", 3)  = "bat"
	 * StringUtil.leftPad("bat", 5)  = "  bat"
	 * StringUtil.leftPad("bat", 1)  = "bat"
	 * StringUtil.leftPad("bat", -1) = "bat"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param size
	 *            扩大后的长度
	 * @return String
	 */
	public static String leftPad(String str, int size) {
		return leftPad(str, size, ' ');
	}

	/**
	 * <p>
	 * 扩大字符串长度，从左边补充指定的字符
	 * </p>
	 *
	 * <pre>
	 * StringUtil.leftPad(null, *, *)     = null
	 * StringUtil.leftPad("", 3, 'z')     = "zzz"
	 * StringUtil.leftPad("bat", 3, 'z')  = "bat"
	 * StringUtil.leftPad("bat", 5, 'z')  = "zzbat"
	 * StringUtil.leftPad("bat", 1, 'z')  = "bat"
	 * StringUtil.leftPad("bat", -1, 'z') = "bat"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param size
	 *            扩大后的长度
	 * @param padChar
	 *            补充的字符
	 * @return String
	 */
	public static String leftPad(String str, int size, char padChar) {
		if (str == null) {
			return null;
		}
		int pads = size - str.length();
		if (pads <= 0) {
			return str; // returns original String when possible
		}
		if (pads > PAD_LIMIT) {
			return leftPad(str, size, String.valueOf(padChar));
		}
		return repeat(padChar, pads).concat(str);
	}

	/**
	 * <p>
	 * 扩大字符串长度，从左边补充指定的字符
	 * </p>
	 *
	 * <pre>
	 * StringUtil.leftPad(null, *, *)      = null
	 * StringUtil.leftPad("", 3, "z")      = "zzz"
	 * StringUtil.leftPad("bat", 3, "yz")  = "bat"
	 * StringUtil.leftPad("bat", 5, "yz")  = "yzbat"
	 * StringUtil.leftPad("bat", 8, "yz")  = "yzyzybat"
	 * StringUtil.leftPad("bat", 1, "yz")  = "bat"
	 * StringUtil.leftPad("bat", -1, "yz") = "bat"
	 * StringUtil.leftPad("bat", 5, null)  = "  bat"
	 * StringUtil.leftPad("bat", 5, "")    = "  bat"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param size
	 *            扩大后的长度
	 * @param padStr
	 *            补充的字符串
	 * @return String
	 */
	public static String leftPad(String str, int size, String padStr) {
		if (str == null) {
			return null;
		}
		if (isEmpty(padStr)) {
			padStr = " ";
		}
		int padLen = padStr.length();
		int strLen = str.length();
		int pads = size - strLen;
		if (pads <= 0) {
			return str; // returns original String when possible
		}
		if (padLen == 1 && pads <= PAD_LIMIT) {
			return leftPad(str, size, padStr.charAt(0));
		}

		if (pads == padLen) {
			return padStr.concat(str);
		} else if (pads < padLen) {
			return padStr.substring(0, pads).concat(str);
		} else {
			char[] padding = new char[pads];
			char[] padChars = padStr.toCharArray();
			for (int i = 0; i < pads; i++) {
				padding[i] = padChars[i % padLen];
			}
			return new String(padding).concat(str);
		}
	}

	/**
	 * <p>
	 * 扩大字符串长度并将现在的字符串居中，被扩大部分用空格填充。
	 * <p>
	 *
	 * <pre>
	 * StringUtil.center(null, *)   = null
	 * StringUtil.center("", 4)     = "    "
	 * StringUtil.center("ab", -1)  = "ab"
	 * StringUtil.center("ab", 4)   = " ab "
	 * StringUtil.center("abcd", 2) = "abcd"
	 * StringUtil.center("a", 4)    = " a  "
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param size
	 *            扩大后的长度
	 * @return String
	 */
	public static String center(String str, int size) {
		return center(str, size, ' ');
	}

	/**
	 * <p>
	 * 将字符串长度修改为指定长度，并进行居中显示。
	 * </p>
	 *
	 * <pre>
	 * StringUtil.center(null, *, *)     = null
	 * StringUtil.center("", 4, ' ')     = "    "
	 * StringUtil.center("ab", -1, ' ')  = "ab"
	 * StringUtil.center("ab", 4, ' ')   = " ab"
	 * StringUtil.center("abcd", 2, ' ') = "abcd"
	 * StringUtil.center("a", 4, ' ')    = " a  "
	 * StringUtil.center("a", 4, 'y')    = "yayy"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param size
	 *            指定的长度
	 * @param padChar
	 *            长度不够时补充的字符串
	 * @return String
	 * @throws IllegalArgumentException
	 *             如果被补充字符串为 null或者 empty
	 */
	public static String center(String str, int size, char padChar) {
		if (str == null || size <= 0) {
			return str;
		}
		int strLen = str.length();
		int pads = size - strLen;
		if (pads <= 0) {
			return str;
		}
		str = leftPad(str, strLen + pads / 2, padChar);
		str = rightPad(str, size, padChar);
		return str;
	}

	/**
	 * <p>
	 * 将字符串长度修改为指定长度，并进行居中显示。
	 * </p>
	 *
	 * <pre>
	 * StringUtil.center(null, *, *)     = null
	 * StringUtil.center("", 4, " ")     = "    "
	 * StringUtil.center("ab", -1, " ")  = "ab"
	 * StringUtil.center("ab", 4, " ")   = " ab"
	 * StringUtil.center("abcd", 2, " ") = "abcd"
	 * StringUtil.center("a", 4, " ")    = " a  "
	 * StringUtil.center("a", 4, "yz")   = "yayz"
	 * StringUtil.center("abc", 7, null) = "  abc  "
	 * StringUtil.center("abc", 7, "")   = "  abc  "
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param size
	 *            指定的长度
	 * @param padStr
	 *            长度不够时补充的字符串
	 * @return String
	 * @throws IllegalArgumentException
	 *             如果被补充字符串为 null或者 empty
	 */
	public static String center(String str, int size, String padStr) {
		if (str == null || size <= 0) {
			return str;
		}
		if (isEmpty(padStr)) {
			padStr = " ";
		}
		int strLen = str.length();
		int pads = size - strLen;
		if (pads <= 0) {
			return str;
		}
		str = leftPad(str, strLen + pads / 2, padStr);
		str = rightPad(str, size, padStr);
		return str;
	}

	/**
	 * <p>
	 * 检查字符串是否全部为小写.
	 * </p>
	 *
	 * <pre>
	 * StringUtil.isAllLowerCase(null)   = false
	 * StringUtil.isAllLowerCase("")     = false
	 * StringUtil.isAllLowerCase("  ")   = false
	 * StringUtil.isAllLowerCase("abc")  = true
	 * StringUtil.isAllLowerCase("abC") = false
	 * </pre>
	 *
	 * @param cs
	 *            源字符串
	 * @return String
	 */
	public static boolean isAllLowerCase(String cs) {
		if (cs == null || isEmpty(cs)) {
			return false;
		}
		int sz = cs.length();
		for (int i = 0; i < sz; i++) {
			if (Character.isLowerCase(cs.charAt(i)) == false) {
				return false;
			}
		}
		return true;
	}

	/**
	 * <p>
	 * 检查是否都是大写.
	 * </p>
	 *
	 * <pre>
	 * StringUtil.isAllUpperCase(null)   = false
	 * StringUtil.isAllUpperCase("")     = false
	 * StringUtil.isAllUpperCase("  ")   = false
	 * StringUtil.isAllUpperCase("ABC")  = true
	 * StringUtil.isAllUpperCase("aBC") = false
	 * </pre>
	 *
	 * @param cs
	 *            源字符串
	 * @return String
	 */
	public static boolean isAllUpperCase(String cs) {
		if (cs == null || isEmpty(cs)) {
			return false;
		}
		int sz = cs.length();
		for (int i = 0; i < sz; i++) {
			if (Character.isUpperCase(cs.charAt(i)) == false) {
				return false;
			}
		}
		return true;
	}

	/**
	 * <p>
	 * 反转字符串.
	 * </p>
	 *
	 * <pre>
	 * StringUtil.reverse(null)  = null
	 * StringUtil.reverse("")    = ""
	 * StringUtil.reverse("bat") = "tab"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @return String
	 */
	public static String reverse(String str) {
		if (str == null) {
			return null;
		}
		return new StringBuilder(str).reverse().toString();
	}

	/**
	 * <p>
	 * 字符串达不到一定长度时在右边补空白.
	 * </p>
	 *
	 * <pre>
	 * StringUtil.rightPad(null, *)   = null
	 * StringUtil.rightPad("", 3)     = "   "
	 * StringUtil.rightPad("bat", 3)  = "bat"
	 * StringUtil.rightPad("bat", 5)  = "bat  "
	 * StringUtil.rightPad("bat", 1)  = "bat"
	 * StringUtil.rightPad("bat", -1) = "bat"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param size
	 *            指定的长度
	 * @return String
	 */
	public static String rightPad(String str, int size) {
		return rightPad(str, size, ' ');
	}

	/**
	 * 从右边截取字符串.</p>
	 *
	 * <pre>
	 * StringUtil.right(null, *)    = null
	 * StringUtil.right(*, -ve)     = ""
	 * StringUtil.right("", *)      = ""
	 * StringUtil.right("abc", 0)   = ""
	 * StringUtil.right("abc", 2)   = "bc"
	 * StringUtil.right("abc", 4)   = "abc"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param len
	 *            长度
	 * @return String
	 */
	public static String right(String str, int len) {
		if (str == null) {
			return null;
		}
		if (len < 0) {
			return EMPTY;
		}
		if (str.length() <= len) {
			return str;
		}
		return str.substring(str.length() - len);
	}

	/**
	 * <p>
	 * 截取一个字符串的前几个.
	 * </p>
	 *
	 * <pre>
	 * StringUtil.left(null, *)    = null
	 * StringUtil.left(*, -ve)     = ""
	 * StringUtil.left("", *)      = ""
	 * StringUtil.left("abc", 0)   = ""
	 * StringUtil.left("abc", 2)   = "ab"
	 * StringUtil.left("abc", 4)   = "abc"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param len
	 *            截取的长度
	 * @return the String
	 */
	public static String left(String str, int len) {
		if (str == null) {
			return null;
		}
		if (len < 0) {
			return EMPTY;
		}
		if (str.length() <= len) {
			return str;
		}
		return str.substring(0, len);
	}

	/**
	 * <p>
	 * 得到tag字符串中间的子字符串，只返回第一个匹配项。
	 * </p>
	 *
	 * <pre>
	 * StringUtil.substringBetween(null, *)            = null
	 * StringUtil.substringBetween("", "")             = ""
	 * StringUtil.substringBetween("", "tag")          = null
	 * StringUtil.substringBetween("tagabctag", null)  = null
	 * StringUtil.substringBetween("tagabctag", "")    = ""
	 * StringUtil.substringBetween("tagabctag", "tag") = "abc"
	 * </pre>
	 *
	 * @param str
	 *            源字符串。
	 * @param tag
	 *            标识字符串。
	 * @return String 子字符串, 如果没有符合要求的，返回{@code null}。
	 */
	public static String substringBetween(String str, String tag) {
		return substringBetween(str, tag, tag);
	}

	/**
	 * <p>
	 * 得到两个字符串中间的子字符串，只返回第一个匹配项。
	 * </p>
	 *
	 * <pre>
	 * StringUtil.substringBetween("wx[b]yz", "[", "]") = "b"
	 * StringUtil.substringBetween(null, *, *)          = null
	 * StringUtil.substringBetween(*, null, *)          = null
	 * StringUtil.substringBetween(*, *, null)          = null
	 * StringUtil.substringBetween("", "", "")          = ""
	 * StringUtil.substringBetween("", "", "]")         = null
	 * StringUtil.substringBetween("", "[", "]")        = null
	 * StringUtil.substringBetween("yabcz", "", "")     = ""
	 * StringUtil.substringBetween("yabcz", "y", "z")   = "abc"
	 * StringUtil.substringBetween("yabczyabcz", "y", "z")   = "abc"
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param open
	 *            起字符串。
	 * @param close
	 *            末字符串。
	 * @return String 子字符串, 如果没有符合要求的，返回{@code null}。
	 */
	public static String substringBetween(String str, String open, String close) {
		if (str == null || open == null || close == null) {
			return null;
		}
		int start = str.indexOf(open);
		if (start != INDEX_NOT_FOUND) {
			int end = str.indexOf(close, start + open.length());
			if (end != INDEX_NOT_FOUND) {
				return str.substring(start + open.length(), end);
			}
		}
		return null;
	}

	/**
	 * <p>
	 * 得到两个字符串中间的子字符串，所有匹配项组合为数组并返回。
	 * </p>
	 *
	 * <pre>
	 * StringUtil.substringsBetween("[a][b][c]", "[", "]") = ["a","b","c"]
	 * StringUtil.substringsBetween(null, *, *)            = null
	 * StringUtil.substringsBetween(*, null, *)            = null
	 * StringUtil.substringsBetween(*, *, null)            = null
	 * StringUtil.substringsBetween("", "[", "]")          = []
	 * </pre>
	 *
	 * @param str
	 *            源字符串
	 * @param open
	 *            起字符串。
	 * @param close
	 *            末字符串。
	 * @return String 子字符串数组, 如果没有符合要求的，返回{@code null}。
	 */
	public static String[] substringsBetween(String str, String open,
											 String close) {
		if (str == null || isEmpty(open) || isEmpty(close)) {
			return null;
		}
		int strLen = str.length();
		if (strLen == 0) {
			return new String[0];
		}
		int closeLen = close.length();
		int openLen = open.length();
		List<String> list = new ArrayList<String>();
		int pos = 0;
		while (pos < strLen - closeLen) {
			int start = str.indexOf(open, pos);
			if (start < 0) {
				break;
			}
			start += openLen;
			int end = str.indexOf(close, start);
			if (end < 0) {
				break;
			}
			list.add(str.substring(start, end));
			pos = end + closeLen;
		}
		if (list.isEmpty()) {
			return null;
		}
		return list.toArray(new String[list.size()]);
	}

	/**
	 * 功能：切换字符串中的所有字母大小写。<br/>
	 *
	 * <pre>
	 * StringUtil.swapCase(null)                 = null
	 * StringUtil.swapCase("")                   = ""
	 * StringUtil.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
	 * </pre>
	 *
	 *
	 * @param str
	 *            源字符串
	 * @return String
	 */
	public static String swapCase(String str) {
		if (isEmpty(str)) {
			return str;
		}
		char[] buffer = str.toCharArray();

		boolean whitespace = true;

		for (int i = 0; i < buffer.length; i++) {
			char ch = buffer[i];
			if (Character.isUpperCase(ch)) {
				buffer[i] = Character.toLowerCase(ch);
				whitespace = false;
			} else if (Character.isTitleCase(ch)) {
				buffer[i] = Character.toLowerCase(ch);
				whitespace = false;
			} else if (Character.isLowerCase(ch)) {
				if (whitespace) {
					buffer[i] = Character.toTitleCase(ch);
					whitespace = false;
				} else {
					buffer[i] = Character.toUpperCase(ch);
				}
			} else {
				whitespace = Character.isWhitespace(ch);
			}
		}
		return new String(buffer);
	}

	/**
	 * 功能：截取出最后一个标志位之后的字符串.<br/>
	 * 如果sourceStr为empty或者expr为null，直接返回源字符串。<br/>
	 * 如果expr长度为0，直接返回sourceStr。<br/>
	 * 如果expr在sourceStr中不存在，直接返回sourceStr。<br/>
	 *
	 * @param sourceStr
	 *            被截取的字符串
	 * @param expr
	 *            分隔符
	 * @return String
	 */
	public static String substringAfterLast(String sourceStr, String expr) {
		if (isEmpty(sourceStr) || expr == null) {
			return sourceStr;
		}
		if (expr.length() == 0) {
			return sourceStr;
		}

		int pos = sourceStr.lastIndexOf(expr);
		if (pos == -1) {
			return sourceStr;
		}
		return sourceStr.substring(pos + expr.length());
	}

	/**
	 * 功能：截取出最后一个标志位之前的字符串.<br/>
	 * 如果sourceStr为empty或者expr为null，直接返回源字符串。<br/>
	 * 如果expr长度为0，直接返回sourceStr。<br/>
	 * 如果expr在sourceStr中不存在，直接返回sourceStr。<br/>
	 *
	 * @param sourceStr
	 *            被截取的字符串
	 * @param expr
	 *            分隔符
	 * @return String
	 */
	public static String substringBeforeLast(String sourceStr, String expr) {
		if (isEmpty(sourceStr) || expr == null) {
			return sourceStr;
		}
		if (expr.length() == 0) {
			return sourceStr;
		}
		int pos = sourceStr.lastIndexOf(expr);
		if (pos == -1) {
			return sourceStr;
		}
		return sourceStr.substring(0, pos);
	}

	/**
	 * 功能：截取出第一个标志位之后的字符串.<br/>
	 * 如果sourceStr为empty或者expr为null，直接返回源字符串。<br/>
	 * 如果expr长度为0，直接返回sourceStr。<br/>
	 * 如果expr在sourceStr中不存在，直接返回sourceStr。<br/>
	 *
	 * @param sourceStr
	 *            被截取的字符串
	 * @param expr
	 *            分隔符
	 * @return String
	 */
	public static String substringAfter(String sourceStr, String expr) {
		if (isEmpty(sourceStr) || expr == null) {
			return sourceStr;
		}
		if (expr.length() == 0) {
			return sourceStr;
		}

		int pos = sourceStr.indexOf(expr);
		if (pos == -1) {
			return sourceStr;
		}
		return sourceStr.substring(pos + expr.length());
	}

	/**
	 * 功能：截取出第一个标志位之前的字符串.<br/>
	 * 如果sourceStr为empty或者expr为null，直接返回源字符串。<br/>
	 * 如果expr长度为0，直接返回sourceStr。<br/>
	 * 如果expr在sourceStr中不存在，直接返回sourceStr。<br/>
	 * 如果expr在sourceStr中存在不止一个，以第一个位置为准。
	 *
	 * @param sourceStr
	 *            被截取的字符串
	 * @param expr
	 *            分隔符
	 * @return String
	 */
	public static String substringBefore(String sourceStr, String expr) {
		if (isEmpty(sourceStr) || expr == null) {
			return sourceStr;
		}
		if (expr.length() == 0) {
			return sourceStr;
		}
		int pos = sourceStr.indexOf(expr);
		if (pos == -1) {
			return sourceStr;
		}
		return sourceStr.substring(0, pos);
	}

	/**
	 * 如果字符串没有超过最长显示长度返回原字符串，否则从开头截取指定长度并加...返回。
	 *
	 * @param str
	 *            原字符串
	 * @param length
	 *            字符串最长显示的长度
	 * @return 转换后的字符串
	 */
	public static String trimString(String str, int length) {
		if (str == null) {
			return "";
		} else if (str.length() > length) {
			return str.substring(0, length - 3) + "...";
		} else {
			return str;
		}
	}

}
